<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  loading?: boolean
  type?: 'spinner' | 'skeleton' | 'progress' | 'pulse'
  size?: 'small' | 'medium' | 'large'
  color?: string
  text?: string
  overlay?: boolean
  fullscreen?: boolean
  transparent?: boolean
  minHeight?: string | number
}

const props = withDefaults(defineProps<Props>(), {
  loading: false,
  type: 'spinner',
  size: 'medium',
  color: 'primary',
  text: '加载中...',
  overlay: false,
  fullscreen: false,
  transparent: false,
  minHeight: '200px'
})

const loaderClasses = computed(() => ({
  'page-loader': true,
  'page-loader--overlay': props.overlay,
  'page-loader--fullscreen': props.fullscreen,
  'page-loader--transparent': props.transparent,
  [`page-loader--${props.size}`]: true
}))

const containerStyle = computed(() => ({
  minHeight: typeof props.minHeight === 'number' ? `${props.minHeight}px` : props.minHeight
}))

const iconSize = computed(() => {
  const sizes = { small: 24, medium: 32, large: 48 }
  return sizes[props.size]
})
</script>

<template>
  <div v-if="loading" :class="loaderClasses" :style="containerStyle">
    <div class="page-loader__content">
      <!-- 旋转加载器 -->
      <template v-if="type === 'spinner'">
        <VProgressCircular
          :size="iconSize"
          :color="color"
          indeterminate
          class="page-loader__spinner"
        />
        <p v-if="text" class="page-loader__text">{{ text }}</p>
      </template>

      <!-- 骨架屏 -->
      <template v-else-if="type === 'skeleton'">
        <div class="page-loader__skeleton">
          <VSkeleton type="heading" class="mb-4" />
          <VSkeleton type="sentences" length="3" />
        </div>
      </template>

      <!-- 进度条 -->
      <template v-else-if="type === 'progress'">
        <div class="page-loader__progress">
          <VProgressLinear
            :color="color"
            indeterminate
            height="4"
            rounded
            class="mb-3"
          />
          <p v-if="text" class="page-loader__text">{{ text }}</p>
        </div>
      </template>

      <!-- 脉冲动画 -->
      <template v-else-if="type === 'pulse'">
        <div class="page-loader__pulse">
          <div class="pulse-dot" :style="{ backgroundColor: `rgb(var(--v-theme-${color}))` }"></div>
          <div class="pulse-dot" :style="{ backgroundColor: `rgb(var(--v-theme-${color}))` }"></div>
          <div class="pulse-dot" :style="{ backgroundColor: `rgb(var(--v-theme-${color}))` }"></div>
        </div>
        <p v-if="text" class="page-loader__text">{{ text }}</p>
      </template>
    </div>
  </div>
</template>

<style scoped>
.page-loader {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  position: relative;
}

.page-loader--overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(2px);
  z-index: 1000;
}

.page-loader--fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
}

.page-loader--transparent {
  background: transparent;
}

.page-loader__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.page-loader__text {
  margin: 0;
  color: #64748b;
  font-weight: 500;
  text-align: center;
}

.page-loader--small .page-loader__text {
  font-size: 0.875rem;
}

.page-loader--medium .page-loader__text {
  font-size: 1rem;
}

.page-loader--large .page-loader__text {
  font-size: 1.125rem;
}

.page-loader__spinner {
  animation: fadeIn 0.3s ease-in;
}

.page-loader__skeleton {
  width: 100%;
  max-width: 400px;
}

.page-loader__progress {
  width: 100%;
  max-width: 300px;
}

.page-loader__pulse {
  display: flex;
  gap: 8px;
  align-items: center;
}

.pulse-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  animation: pulse 1.4s ease-in-out infinite both;
}

.pulse-dot:nth-child(2) {
  animation-delay: 0.2s;
}

.pulse-dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: scale(0.8);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes pulse {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1.2);
    opacity: 1;
  }
}
</style>
